/**
 * \file    item.h
 * \brief   Parser generator.
 * \author  Jérôme LAURENS
 * \version 0.1
 * \date    September 23, 2014
 *
 * Reads a LALR(1) grammar, generates a parser based on a template file.
 * This is based on lemon parser generator, but has strongly been
 * revisited.
 *
 */

#ifndef ITEM_H
#define ITEM_H

#include "rule.h"
#include "common.h"
#include "state.h"
#include "symbol.h"

LPP_NAMESPACE_BEGIN

class Item {
public:
    typedef Item __self;
    static ItemRef Make(  StateRef const & state
                  , RuleRef const & __r
                  , SymbolIndex const __d ) {
        static Index id = 0;
        return std::make_shared<Item>(id++,state, __r, __d);
    }

    Item (  Index const id
            , StateRef const & state
            , RuleRef const & __r
            , SymbolIndex const __d )
        : id_m(id)
        , state_m(state)
        , rule_m(__r)
        , dot_m(__d) {}
    RuleRef const & rule() const {
        return rule_m;
    }
    SymbolIndex dot() const {
        return dot_m;
    }

    String description() const;
    String short_description() const;

    SymbolRef const symbol_after_dot() const {
        return rule_m->rhs_symbols()[dot_m];
    }
    bool is_at_end() const {
        return rule_m->is_at_end(dot_m);
    }
    Index id() const {
        return id_m;
    }
    SymbolRefList const get_first_set() const {/*! first set, of the lhs, the callee is the owner. */
        if (is_at_end()) return SymbolRefList({});
        return symbol_after_dot()->get_first_set();
    }

private:
    Index id_m;
    StateWRef const state_m;
    RuleRef const rule_m;         /* The rule upon which the Item is based */
    SymbolIndex dot_m;                 /* The parse point */
    Item(Item const & item);
    Item & operator = (Item const & item);

};

LPP_NAMESPACE_END

#endif // ITEM_H
